package com.ukefu.webim.web.handler.api.rest;

import static org.elasticsearch.index.query.QueryBuilders.termQuery;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.webim.service.es.FavoritesRepository;
import com.ukefu.webim.service.es.WorkOrdersRepository;
import com.ukefu.webim.service.repository.AttachmentRepository;
import com.ukefu.webim.service.repository.OrganRepository;
import com.ukefu.webim.service.repository.OrgiSkillRelRepository;
import com.ukefu.webim.service.repository.TagRepository;
import com.ukefu.webim.service.repository.UserRepository;
import com.ukefu.webim.util.RestResult;
import com.ukefu.webim.util.RestResultType;
import com.ukefu.webim.util.WorkOrdersUtils;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.handler.api.request.SearchData;
import com.ukefu.webim.web.model.Favorites;
import com.ukefu.webim.web.model.Organ;
import com.ukefu.webim.web.model.OrgiSkillRel;
import com.ukefu.webim.web.model.User;
import com.ukefu.webim.web.model.WorkOrders;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/api/workorders")
@Api(value = "工单服务", description = "工单管理功能")
public class ApiWorkOrdersController extends Handler{
	
	@Value("${web.upload-path}")
    private String path;

	@Autowired
	private AttachmentRepository attachementRes;

	@Autowired
	private WorkOrdersRepository workOrdersRepository;
	
	@Autowired
	private FavoritesRepository favRes ;
	
	@Autowired
	private TagRepository tagRes;
	
	@Autowired
	private OrgiSkillRelRepository orgiSkillRelService;
	
	@Autowired
	private OrganRepository organRes ;
	
	@Autowired
	private UserRepository userRes ;

	/**
	 * 返回用户列表，支持分页，分页参数为 p=1&ps=50，默认分页尺寸为 20条每页
	 * @param request
	 * @param q
	 * @return
	 */
	@RequestMapping( method = RequestMethod.GET)
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("返回我创建的工单")
    public ResponseEntity<RestResult> list(HttpServletRequest request , @Valid String q) {
		Page<WorkOrders> workOrdersList = null ;
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	BoolQueryBuilder myBuilder = QueryBuilders.boolQuery();
    	myBuilder.should(termQuery("creater" , super.getUser(request).getId())) ;
    	
    	boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	
    	boolQueryBuilder.must(myBuilder) ;
    	workOrdersList = workOrdersRepository.findByCreater(boolQueryBuilder, false  , false , q, super.getUser(request).getId() ,  new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "updatetime")) ;
    	
    	if (workOrdersList != null && workOrdersList.getSize() >0) {
			for(WorkOrders wo : workOrdersList) {
				if (wo.getUser()!=null) {
					wo.getUser().setPassword(null);
				}
				if (wo.getCurrent()!=null) {
					wo.getCurrent().setPassword(null);
				}
			}
		}
    	
        return new ResponseEntity<>(new RestResult(RestResultType.OK, new SearchData<WorkOrders>(workOrdersList)), HttpStatus.OK);
    }
	
	/**
	 * 新增或修改工单信息
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping(method = RequestMethod.PUT)
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("新建工单，自动分配工单编号")
    public ResponseEntity<RestResult> put(HttpServletRequest request , @Valid WorkOrders workOrders, @Valid MultipartFile[] files) throws IOException {
		RestResult result = new RestResult(RestResultType.OK) ; 
		if(workOrders != null && !StringUtils.isBlank(workOrders.getTitle())){
    		workOrders.setOrgi(super.getOrgi(request));
        	workOrders.setCreater(super.getUser(request).getId());
        	workOrders.setUsername(super.getUser(request).getUsername());
        	
        	workOrders.setOrgan(super.getUser(request).getOrgan());
        	workOrders.setCreatetime(new Date());

			String orderNo = String.valueOf(WorkOrdersUtils.getWorkOrderNumber(super.getOrgi(request)));
			List<WorkOrders> orderNoList = null;
			do {
				orderNoList	= workOrdersRepository.findByOrdernoAndOrgi(orderNo,super.getOrgi(request));
				if(orderNoList != null && orderNoList.size() > 0){
					orderNo = String.valueOf(WorkOrdersUtils.getWorkOrderNumber(super.getOrgi(request)));
				}
			}while (orderNoList != null && orderNoList.size() > 0);


			workOrders.setOrderno(orderNo);
        	if(!StringUtils.isBlank(workOrders.getAccuser())){
        		workOrders.setAssigned(true) ;
        	}else{
        		workOrders.setAssigned(false) ;
        	}
        	
        	if(files!=null && files.length > 0){
        		UKTools.processAttachmentFile(files, attachementRes , path, super.getUser(request) , super.getOrgi(request), workOrders, request, workOrders.getId(), workOrders.getId());
        	}
        	
        	workOrdersRepository.save(workOrders) ;
        	result.setData(workOrders);
        	
    	}
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
	
	/**
	 * 删除用户，只提供 按照用户ID删除 ， 并且，不能删除系统管理员
	 * @param request
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.DELETE)
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("删除工单，只提供 按照工单ID删除 ， 工单删除是逻辑删除，将该条数据标记为已删除")
    public ResponseEntity<RestResult> delete(HttpServletRequest request , @Valid String id) {
		RestResult result = new RestResult(RestResultType.OK) ; 
    	WorkOrders workOrders = null ;
    	if(!StringUtils.isBlank(id)){
    		workOrders = workOrdersRepository.findByIdAndOrgi(id,super.getOrgi(request)) ;
    		if(workOrders!=null){	//工单是否存在
    			workOrders.setDatastatus(true);
    			workOrdersRepository.save(workOrders) ;
    		}else{
    			result.setStatus(RestResultType.WORKORDERS_DELETE);
    		}
    	}
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
	
	@RequestMapping(value="/search/index")
	@Menu(type = "apps" , subtype = "workOrders" , access = true)
	@ApiOperation("返回指定条件下的工单列表")
    public ResponseEntity<RestResult> searchList(HttpServletRequest request , @Valid String q, @Valid String searchtype) {
		Page<WorkOrders> workOrdersList = null ;
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	BoolQueryBuilder myBuilder = QueryBuilders.boolQuery();
    	
    	if("1".equals(searchtype)){
    		
    		//全部工单
    		myBuilder.should(termQuery("accuser" , super.getUser(request).getId()));
    		myBuilder.should(termQuery("creater" , super.getUser(request).getId())) ;
    	}else if("2".equals(searchtype)){
    		
    		//未分配
    		myBuilder.must(termQuery("creater" , super.getUser(request).getId()));
    		myBuilder.must(QueryBuilders.existsQuery("accuser"));
    	}else if("3".equals(searchtype)){
    		
    		//待处理
    		boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    		myBuilder.should(termQuery("accuser" , super.getUser(request).getId())) ;
    	}else if("4".equals(searchtype)){
    		
    		//已关闭
    		boolQueryBuilder.must(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    		myBuilder.should(termQuery("accuser" , super.getUser(request).getId()));
    		myBuilder.should(termQuery("creater" , super.getUser(request).getId())) ;
    	}
    	
    	if(!StringUtils.isBlank(q)){
	    	boolQueryBuilder.must(new QueryStringQueryBuilder(q).defaultOperator(Operator.AND)) ;
	    }
    	
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request)));
    	boolQueryBuilder.must(myBuilder) ;
    	workOrdersList = workOrdersRepository.findById(boolQueryBuilder, false, super.getOrgi(request),  new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "updatetime"));
    	if (workOrdersList != null && workOrdersList.getSize() >0) {
			for(WorkOrders wo : workOrdersList) {
				if (wo.getUser()!=null) {
					wo.getUser().setPassword(null);
				}
				if (wo.getCurrent()!=null) {
					wo.getCurrent().setPassword(null);
				}
			}
		}
        return new ResponseEntity<>(new RestResult(RestResultType.OK, new SearchData<WorkOrders>(workOrdersList)), HttpStatus.OK);
    }
	
	@RequestMapping(value="/detail")
	@Menu(type = "apps" , subtype = "workOrders" , access = true)
	@ApiOperation("返回指定工单详情")
    public ResponseEntity<RestResult> detail(HttpServletRequest request , @Valid String id) {
		WorkOrders workOrders = null ;
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request)));
    	boolQueryBuilder.must(termQuery("id" , id));
    	workOrders = workOrdersRepository.findByIdAndOrgi(id,super.getOrgi(request)) ;
    	if (workOrders != null) {
    		if (workOrders.getUser()!=null) {
    			workOrders.getUser().setPassword(null);
    		}
    		if (workOrders.getCurrent()!=null) {
    			workOrders.getCurrent().setPassword(null);
    		}
		}
        return new ResponseEntity<>(new RestResult(RestResultType.OK, workOrders), HttpStatus.OK);
    }
	
	@RequestMapping(value="/fav/order")
	@Menu(type = "apps" , subtype = "user" , access = true)
	@ApiOperation("关注工单")
    public ResponseEntity<RestResult> favorder(HttpServletRequest request , @Valid String id ) throws IOException {
		if(!StringUtils.isBlank(id)){
			Favorites fav = new Favorites();
			fav.setCode("true");
			fav.setOrderid(id);
    		List<Favorites> favList = favRes.findByOrderidAndOrgiAndCreater(fav.getOrderid() , super.getOrgi(request),super.getUser(request).getId()) ;
    		if(favList.size() > 0){
    			Favorites f = favList.get(0);
    			if("false".equals(f.getCode())) {
    				f.setCode("true");
    			}else {
    				f.setCode("false");
    			}
    			favRes.save(f);
    		}else{
	    		fav.setOrgi(super.getOrgi(request));
	    		fav.setCreater(super.getUser(request).getId());
	    		fav.setCreatetime(new Date());
	    		fav.setModel(UKDataContext.ModelType.WORKORDERS.toString());
	    		fav.setUsername(super.getUser(request).getUsername());
	    		favRes.save(fav) ;
    		}
    	}
        return new ResponseEntity<>(new RestResult(RestResultType.OK), HttpStatus.OK);
    }
	 
	
	
	/**
	 * 获取工单标签列表
	 * @param request
	 * @param type 类型
	 * @return
	 */
	@RequestMapping("/tags")
	@Menu(type = "apps" , subtype = "workOrders" , access = true)
	    public ResponseEntity<RestResult> list(HttpServletRequest request) {
        return new ResponseEntity<>(new RestResult(RestResultType.OK, tagRes.findByOrgiAndTagtype(super.getOrgi(request) , UKDataContext.ModelType.WORKORDERS.toString())), HttpStatus.OK);
    }
	
	/**
	 * 获取受理人列表
	 * @param request
	 * @param type 类型
	 * @return
	 */
	@RequestMapping("/accuserlist")
	@Menu(type = "apps" , subtype = "workOrders" , access = true)
	    public ResponseEntity<RestResult> accuserlist(HttpServletRequest request,@Valid String organ) {
        return new ResponseEntity<>(new RestResult(RestResultType.OK, getUsers(request,organ)), HttpStatus.OK);
    }
	
	/**
	 * 获取受理部门列表
	 * @param request
	 * @param type 类型
	 * @return
	 */
	@RequestMapping("/accdeptlist")
	@Menu(type = "apps" , subtype = "workOrders" , access = true)
	    public ResponseEntity<RestResult> accdeptlist(HttpServletRequest request) {
        return new ResponseEntity<>(new RestResult(RestResultType.OK, getOrgans(request)), HttpStatus.OK);
    }
	
	private List<Organ> getOrgans(HttpServletRequest request){
    	List<Organ> list = null;
    	if(super.isTenantshare()) {
			List<String> organIdList = new ArrayList<>();
			List<OrgiSkillRel> orgiSkillRelList = orgiSkillRelService.findByOrgi(super.getOrgi(request)) ;
			if(!orgiSkillRelList.isEmpty()) {
				for(OrgiSkillRel rel:orgiSkillRelList) {
					organIdList.add(rel.getSkillid());
				}
			}
			list = organRes.findByIdInAndOrgi(organIdList,super.getOrgi(request));
		}else {
			list = organRes.findByOrgiAndOrgid(super.getOrgi(request),super.getOrgid(request)) ;
		}
    	return list;
    }
    private List<User> getUsers(HttpServletRequest request,String organ){
    	List<User> list = null;
    	if (!StringUtils.isBlank(organ)) {
    		list = userRes.findByOrganAndDatastatusAndOrgi(organ, false, super.getOrgi(request));
		}else{
			if(super.isTenantshare()) {
				List<String> organIdList = new ArrayList<>();
				List<OrgiSkillRel> orgiSkillRelList = orgiSkillRelService.findByOrgi(super.getOrgi(request)) ;
				if(!orgiSkillRelList.isEmpty()) {
					for(OrgiSkillRel rel:orgiSkillRelList) {
						organIdList.add(rel.getSkillid());
					}
				}
				list = userRes.findByOrganInAndDatastatusAndOrgi(organIdList,false ,super.getOrgi(request));
			}else {
				list = userRes.findByOrgiAndDatastatus(super.getOrgi(request),false) ;
			}
		}
    	if (list != null && list.size()>0) {
			for(User u : list) {
				u.setPassword(null);
			}
		}
    	return list;
    }
}